<!-- 
  1. 三方组件使用
    一般模式
    1. npm包的方式进行安装 
    2. main.js中进行导入  import ElementUI from 'element'
    3. Vue.use(ElementUI) -> 调用组件内部index.js入口文件中的install(Vue)  Vue.component(全局组件)/Vue.protype.$confirm

    具体用法
    1. props  
       <el-button type="success" :flag="true" :list="[1,2,3]"></el-button>
       数据类型 / 是否加冒号(识别为响应式数据,识别为有类型的数据)

    2. 自定义事件
       某个功能如果想要获取子组件中的数据
       某个功能的触发需要在子组件内往外通知

       $emit('自定义事件')  ->  父组件中使用 <el-button @自定义事件="clickHandler"></el-button>

       @current-change="handler"

       methods:{
         handler(page){
          console.log(page)
         }
       }

    3. 插槽
       定制某个组件内部显示的内容 传递的是HTML模板

       组件标签内部默认情况下写的所有东西都会被自动忽略

       <foo-component>
        // 这里不能写东西识别不了
       </foo-component>

       定义这个组件的时候需要加上一个内置的组件<slot/>

       具体使用
         table
          1. 自定义操作栏 
          2. 根据后端返回的状态码渲染文本

         <template #default>
           <el-button>删除</el-button>
         </template>
         
         <template #default="scope">
           <el-button @click="hanlder(scope.row.id)">删除</el-button>
         </template>


    4. 函数调用内置方法
      在多个组件组合起来才能实现一个完整的功能 
      兜底校验
      1. 通过ref拿到组件实例对象
      2. 通过实例对象调用实例上的某个方法实现功能

      this.$refs.form.validate((valid)=>{
         if(valid){
            // todo 登录操作
         }
      })

  2. vue-admin-template
      提供了后台管理系统基础架构的适合于二次开发的架子
      main.js  入口文件
        elementUI初始化
        初始化路由
        初始化vuex
        vue实例化

      app.vue
        组件树里面的根组件 组件渲染的起点
        <router-view/> 路由出口  当前的url路由标识匹配到了哪个组件 就在router-view位置进行渲染

      permission.js
        权限控制  
          router.beforeEach()
          菜单权限控制 

      store
        vuex相关代码 基于模块化管理 （复用 / 方便维护）
        modules：{模块名称}

      router
        模块化管理
        动态路由(可以根据用户权限发生改变的路由) + 静态路由(任何一个用户进来都是一样)

        new VueRouter({
          routes:[...动态路由表,...静态路由表]
        })


  3. 登录业务(token)
     1. 表单校验
        el-form   绑定表单对象model  绑定校验规则rules
        el-form-item  prop属性指定当前表单域要采用哪个规则
        el-input  v-model做数据的双向绑定

        注意事项: model字段名称 = rules里面字段名称 = prop指定的字段名称

     2. 调用登录接口获取token
        使用vuex进行token管理
        state -> mutation -> action
        在表单验证通过之后 调用action函数

  4. token
     1. 持久化
        前提: vuex基于内存的管理机制刷新浏览器会丢失 + localstorage（cookies）
        方案：
          1. 获取token
          2. 一式俩份  vuex  ls
          3. vuex state初始化化的地方 先从本地取 然后在初始化成空
             state:{
               token: getToken() || ''
             }
        vuex vs ls
          vuex基于内存  刷新丢失  存取速度非常快  响应式
          ls基于磁盘  持久化  存取速度慢

     2. 接口数据鉴权使用
        后端接收到某个请求来了 会先在请求体中拿到token 如果有且有效才把当前接口的数据返回
        否则会返回一个401 不包含实际的数据

        方案：
          axios请求拦截器 在正式接口发送之前 先拦截请求 在request headers中注入token


     3. 页面跳转控制
        应用中的某些页面只有登录之后才有权利访问 token

        方案：
          路由全局导航前置守卫  

          router.beforeEach((to,from,next)=>{
            // to: 目标路由对象 path
            // next 可执行的放行函数
            if(token){
              if(to.path === '/login'){
                next('/')
              }else{
                next()
              }
            }else{
              if(whiteList.includes(to.path)){
                next()
              }else{
                next('/login')
              }
            }
          })



  5. vuex相关

     1. vuex
        1. 在vuex中定义数据 定义数据修改方法  定义异步请求action
        2. 业务组件或者模块中 dispatch方法调用action函数

     2. dev-tools
        mutaion函数和state俩者之间的关系

        每一次的mutation函数调用都会在调试工具中形成一条记录 
        记录了在什么时间下通过调用了哪个mutation函数 传递了什么参数 把state中的数据修改成了什么样子

        调试：mutation函数是否调用 -> payload的位置参数是否ok -> state

     3. 业务组件中使用vuex中的数据 或者 方法调用 
        
        数据   mapState mapGetters + 组件中的computed
         state 
         getters

        方法  mapAtions mapMutations  + 组件中的methods
         mutations
         actions

        
      4. action函数 promise化

         actions:{
           asyncSetToken(){
             return new Promise((resolve)=>{
               login().then(res=>{
                 resolve()
               })
             })
           }
         }

         dispatch(asyncSetToken).then(res=>{
           // 跳转
         })

  6. request.js
       axios封装
         1. 实例化 axios.create() 
            baseURL
            timeout
            大数处理

         2. 请求拦截器
            token注入

         3. 响应拦截器
            token失效 401
            当后端接口返回的成功失败判断表示不是以http状态码作为判断依据 
            不管成功还是失败 走http = 200  导致业务接口调用的catch函数中捕获不到当前错误

            技术解决：
              在响应拦截器中的成功函数中做判断
              拿到当前判断表示  success 如果true 直接把数据return出去   如果false 手动抛出错误  
 -->